package com.sunye;

import com.alibaba.fastjson.JSON;
import jdk.nashorn.internal.objects.annotations.Getter;
import jdk.nashorn.internal.objects.annotations.Setter;
import org.junit.platform.commons.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class Person {
    private Integer id;
    private String name;
    private Integer age;

    public Person(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public static void main(String[] args){
        List<Person> list = new ArrayList<>();
        list.add(new Person(3,"王五",10));
        list.add(new Person(4,"王五",40));
        list.add(new Person(5,"王五",40));
        list.add(new Person(1,"张三",20));
        list.add(new Person(2,"李四",20));
        List<String> listString = Arrays.asList("1","2");
        System.out.println("当前list = " + JSON.toJSONString(list));
        System.out.println("当前数组 = " + JSON.toJSONString(list.toArray()));
        System.out.println("当前listString = " + JSON.toJSONString(listString));
        System.out.println("当前listStringArray = " + JSON.toJSONString(listString.toArray()));
        //箭头左边是参数
        //箭头右边是执行的方法
        //map提取元素
        List<Integer> integerList = list.stream().map((item) -> {
           return item.getId();//return中止本次循环
        }).collect(Collectors.toList());
        System.out.println("integerList = " + JSON.toJSONString(integerList));
        //简写方案(方法体是一行  不需要写return)
        List<Integer> integerList2 = list.stream().map(item -> item.getId()).collect(Collectors.toList());
        System.out.println("integerList2 = " + JSON.toJSONString(integerList2));
        //方法的引用
        List<Integer> integerList3 = list.stream().map(Person::getId).collect(Collectors.toList());
        System.out.println("integerList3 = " + JSON.toJSONString(integerList3));



        //list转map
        Map<Integer, String> map = list.stream().collect(Collectors.toMap(item -> item.getId(), item2 -> item2.getName()));
        System.out.println("map="+JSON.toJSONString(map));
        List<Person> list2 = new ArrayList<>();
        list2.add(new Person(1,"张三",10));
        //取出key一致的
        List<Person> collect = list2.stream()
                .distinct()//去重
                .filter(item -> { //过滤
            return map.containsKey(item.getId());//过滤
        }).collect(Collectors.toList());
        System.out.println("collect = " + JSON.toJSONString(collect));
        //简写方案(方法体是一行  不需要写return)
        List<Person> collect2 = list2.stream()
                .distinct()//去重
                .filter(item ->  map.containsKey(item.getId())).collect(Collectors.toList());
        System.out.println("collect2 = " + JSON.toJSONString(collect2));
        //使用map过滤
        List<Person> collect3 = list2.stream()
                .distinct()
                .map(item ->{
                    map.containsKey(item.getId());
                    return item;
                }).collect(Collectors.toList());
        System.out.println("collect3 = " + JSON.toJSONString(collect3));
        //分组
        Map<String, List<Person>> groupByList = list.stream().collect(Collectors.groupingBy(item -> item.getName()));
        System.out.println("groupByList = " + groupByList);
        for(String key:groupByList.keySet()){
            List<Person> noExitsList = groupByList.get(key);
            System.out.println("noExitsList = " + JSON.toJSONString(noExitsList));
        }
        //分区--大于20在一起，其余的在一起
        Map<Boolean, List<Person>> partitioningList = list.stream().collect(Collectors.partitioningBy(item -> item.getAge()>20));
        for (Boolean aBoolean : partitioningList.keySet()) {
            List<Person> list1 = partitioningList.get(aBoolean);
            System.out.println("list1 = " + JSON.toJSONString(list1));
        }
        //聚合操作
        IntSummaryStatistics statistics = list.stream().collect(Collectors.summarizingInt(item -> item.getAge()));
        System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());

        //对list排序
        Comparator<Person> personComparator =
                 Comparator.comparing(Person::getAge) //sort by age
                .thenComparing(Person::getName) //then sort by Person name
                .thenComparing(Person::getId); //then sort by Person getId
        Collections.sort(list, personComparator);
        System.out.println("listSort = " + JSON.toJSONString(list));
        List<Person> listSort2 = list.stream()
                .sorted((o1, o2) -> {
                    if (o1.getAge().equals(o2.getAge())) {
                        if (o1.getName().equals(o2.getName())) {
                            return o1.getId().compareTo(o2.getId());
                        } else {
                            return o1.getName().compareTo(o2.getName());
                        }
                    } else {
                        return o1.getAge().compareTo(o2.getAge());
                    }
                }).collect(Collectors.toList());
        System.out.println("listSort2 = "+JSON.toJSONString(listSort2));
        List<Map<Integer,Integer>> listmap = new ArrayList();
        Map map1 = new HashMap();
        map1.put("age",10);
        map1.put("id",2);
        listmap.add(map1);
        Map map2 = new HashMap();
        map2.put("age",20);
        map2.put("id",1);
        listmap.add(map2);
        Map map3 = new HashMap();
        map3.put("age",20);
        map3.put("id",3);
        listmap.add(map3);
        //(1)
        Comparator<Map<Integer, Integer>> ageSort = (o1, o2) -> o1.get("age").compareTo(o2.get("age"));// 升序排列可以不写默认的
        Comparator<Map<Integer, Integer>> idSort = (o1, o2) -> o2.get("id").compareTo(o1.get("id"));//降序排列
        listmap.sort(ageSort.thenComparing(idSort));
        System.out.println("listmap = " + JSON.toJSONString(listmap));
        //(2)常用
        List<Map<Integer, Integer>> listmap2 = listmap.stream()
                .sorted(((o1, o2) -> {
                    if (o1.get("age").equals(o2.get("age"))) {
                        return o2.get("id").compareTo(o1.get("id"));
                    } else {
                        return o1.get("age").compareTo(o2.get("age"));
                    }
                })).collect(Collectors.toList());
        System.out.println("listmap2 = " + JSON.toJSONString(listmap2));


        //peek不改变原有结构返回的List<Person>
        List<Person> peekList1 = list.stream().peek((item) -> {
            item.setName("peek使用");
        }).collect(Collectors.toList());
        System.out.println("peekList1 = " + JSON.toJSONString(peekList1));


        //把list中和list2名字一样的查出来
        List<Person> personList = list.stream().peek(item -> {
            list2.forEach(item2 -> {
                if (item.getId().equals(item2.getId())) {
                    item.setName("和我一样名字");
                }
            });
        }).collect(Collectors.toList());
        System.out.println("personList = " + JSON.toJSONString(personList));

        //自定义去重
        list.stream().filter(distinctByVariable(item ->{
            return  item.getName()+item.getAge();
        })).collect(Collectors.toList());

        //flatMap 转换为另一个流
    }


    private static <T> Predicate<T> distinctByVariable(Function<? super T, ?> keyExtractor) {
        HashMap<Object, Boolean> map = new HashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }



}
